学习node.JS前我们需要提前了解的前置知识(三) | 您所在的位置:网站首页 › node 引入js › 学习node.JS前我们需要提前了解的前置知识(三) |
开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第21天,点击查看活动详情 三、模块/包 与 CommonJS 1、模块/包分类Node.js 有三类模块,即内置的模块、第三方的模块、自定义的模块。 1.1 内置的模块Node.js 内置模块又叫核心模块,Node.js安装完成可直接使用。如: const path = require('path') var extname = path.extname('index.html') console.log(extname) 复制代码 1.2 第三方的Node.js模块第三方的Node.js模块指的是为了实现某些功能,发布的npmjs.org上的模块,按照一定的开源协议供社群使用。如: npm install chalk 复制代码 const chalk = require('chalk') console.log(chalk.blue('Hello world!')) 复制代码 1.3 自定义的Node.js模块自定义的Node.js模块,也叫文件模块,是我们自己写的供自己使用的模块。同时,这类模块发布到npmjs.org上就成了开源的第三方模块。 自定义模块是在运行时动态加载,需要完整的路径分析、文件定位、编译执行过程、速度相比核心模块稍微慢一些,但是用的非常多。 1.3.1 模块定义、接口暴露和引用接口我们可以把公共的功能 抽离成为一个单独的 js 文件 作为一个模块,默认情况下面这个模块里面的方法或者属性,外面是没法访问的。如果要让外部可以访问模块里面的方法或者属性,就必须在模块里面通过 exports 或者module.exports暴露属性或者方法。 m1.js: const name = 'zayyo' const sayName = () => { console.log(name) } console.log('module 1') // 接口暴露方法一: module.exports = { say: sayName } // 接口暴露方法二: exports.say = sayName // 错误! exports = { say: sayName } 复制代码main.js: const m1 = require('./m1') m1.say() 复制代码 1.3.2 模块的循环引用由于 exports 使用方式方式不对,会在两个不同 js 循环引用的情况下,导致其中一个 js 无法获取另外一个 js 的方法,从而导致执行报错。如: a.js exports.done = false const b = require('./b.js') console.log('in a, b.done = %j', b.done) exports.done = true console.log('a done') 复制代码 b.js console.log('b starting') exports.done = false const a = require('./a.js') console.log('in b, a.done = %j', a.done) exports.done = true console.log('b done') 复制代码 main.js console.log('main starting') const a = require('./a.js') const b = require('./b.js') console.log('in main, a.done = %j, b.done = %j', a.done, b.done) 复制代码main.js 首先会 load a.js, 此时执行到const b = require('./b.js');的时候,程序会转去loadb.js, 在b.js中执行到const a = require('./a.js'); 为了防止无限循环,将a.jsexports的未完成副本返回到b.js模块。然后b.js完成加载,并将其导出对象提供给a.js模块。 我们知道nodeJs的对每个js文件进行了一层包装称为module,module中有一个属性exports,当调用require('a.js')的时候其实返回的是module.exports对象,module.exports初始化为一个{}空的object,所以在上面的例子中,执行到b.js中const a = require('./a.js');时不会load新的a module, 而是将已经load但是还未完成的a module的exports属性返回给b module,所以b.js拿到的是a module的exports对象,即:{done:false}, 虽然在a.js中exports.done被修改成了true,但是由于此时a.js未load完成,所以在b.js输出的a module的属性done为false,而在main.js中输出的a module的属性done为true. Nodejs通过上面这种返回未完成exports对象来解决循环引用的问题。 |
CopyRight 2018-2019 实验室设备网 版权所有 |